home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / ASSEMBLE / H145.ZIP / ASXXXX_3.ZIP / LKAREA.C < prev    next >
C/C++ Source or Header  |  1990-07-18  |  3KB  |  193 lines

  1. /* lkarea.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989,1990
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <alloc.h>
  15. #include "aslink.h"
  16.  
  17. /*
  18.  * Create an area entry.
  19.  *
  20.  * A xxxxxx size nnnn flags mm
  21.  *   |           |          |
  22.  *   |           |          `--  ap->a_flag
  23.  *   |           `------------- axp->a_size
  24.  *   `-------------------------  ap->a_id
  25.  *
  26.  */
  27. VOID
  28. newarea()
  29. {
  30.     register i, narea;
  31.     struct areax *taxp;
  32.     struct areax **halp;
  33.     char id[NCPS];
  34.  
  35.     /*
  36.      * Create Area entry
  37.      */
  38.     getid(id, -1);
  39.     lkparea(id);
  40.     /*
  41.      * Evaluate area size
  42.      */
  43.     skip(-1);
  44.     axp->a_size = eval();
  45.     /*
  46.      * Evaluate flags
  47.      */
  48.     skip(-1);
  49.     i = 0;
  50.     taxp = ap->a_axp;
  51.     while (taxp->a_axp) {
  52.         ++i;
  53.         taxp = taxp->a_axp;
  54.     }
  55.     if (i == 0) {
  56.         ap->a_flag = eval();
  57.     } else {
  58.         i = eval();
  59.         if (i && (ap->a_flag != i))
  60.             fprintf(stderr, "Conflicting flags in area %.8s\n", id);
  61.     }
  62.     /*
  63.      * Place pointer in header area list
  64.      */
  65.     if (headp == NULL) {
  66.         fprintf(stderr, "No header defined\n");
  67.         exit(1);
  68.     }
  69.     narea = hp->h_narea;
  70.     halp = hp->a_list;
  71.     for (i=0; i < narea ;++i) {
  72.         if (halp[i] == NULL) {
  73.             halp[i] = taxp;
  74.             return;
  75.         }
  76.     }
  77.     fprintf(stderr, "Header area list overflow\n");
  78.     exit(1);
  79. }
  80.  
  81. /*
  82.  * Lookup the area `id'.
  83.  * If it is not found create it.
  84.  * Then append an area extension.
  85.  */
  86. VOID
  87. lkparea(id)
  88. char *id;
  89. {
  90.     register struct area *tap;
  91.     register struct areax *taxp;
  92.  
  93.     ap = areap;
  94.     axp = (struct areax *) new (sizeof(struct areax));
  95.     while (ap) {
  96.         if (symeq(id, ap->a_id)) {
  97.             taxp = ap->a_axp;
  98.             while (taxp->a_axp)
  99.                 taxp = taxp->a_axp;
  100.             taxp->a_axp = axp;
  101.             axp->a_bap = ap;
  102.             axp->a_bhp = hp;
  103.             return;
  104.         }
  105.         ap = ap->a_ap;
  106.     }
  107.     ap = (struct area *) new (sizeof(struct area));
  108.     if (areap == NULL) {
  109.         areap = ap;
  110.     } else {
  111.         tap = areap;
  112.         while (tap->a_ap)
  113.             tap = tap->a_ap;
  114.         tap->a_ap = ap;
  115.     }
  116.     ap->a_axp = axp;
  117.     axp->a_bap = ap;
  118.     axp->a_bhp = hp;
  119.     strncpy(ap->a_id, id, NCPS);
  120. }
  121.  
  122. /*
  123.  * Resolve all area addresses.
  124.  */
  125. VOID
  126. lnkarea()
  127. {
  128.     register rloc;
  129.  
  130.     rloc = 0;
  131.     ap = areap;
  132.     while (ap) {
  133.         if (ap->a_flag&A_ABS) {
  134.             /*
  135.              * Absolute sections
  136.              */
  137.             lnksect(ap);
  138.         } else {
  139.             /*
  140.              * Relocatable sections
  141.              */
  142.             if (ap->a_addr == 0)
  143.                 ap->a_addr = rloc;
  144.             lnksect(ap);
  145.             rloc = ap->a_addr + ap->a_size;
  146.         }
  147.         ap = ap->a_ap;
  148.     }
  149. }
  150.  
  151. /*
  152.  * Resolve section addresses within an area.
  153.  */
  154. VOID
  155. lnksect(tap)
  156. register struct area *tap;
  157. {
  158.     register addr_t size, addr;
  159.     register struct areax *taxp;
  160.  
  161.     size = 0;
  162.     addr = tap->a_addr;
  163.     if ((tap->a_flag&A_PAG) && (addr & 0xFF))
  164.         fprintf(stderr,
  165.             "\n?ASlink-W-Paged Area %.8s Boundary Error\n", tap->a_id);
  166.     taxp = tap->a_axp;
  167.     if (tap->a_flag&A_OVR) {
  168.         /*
  169.          * Overlayed sections
  170.          */
  171.         while (taxp) {
  172.             taxp->a_addr = addr;
  173.             if (taxp->a_size > size)
  174.                 size = taxp->a_size;
  175.             taxp = taxp->a_axp;
  176.         }
  177.     } else {
  178.         /*
  179.          * Concatenated sections
  180.          */
  181.         while (taxp) {
  182.             taxp->a_addr = addr;
  183.             addr += taxp->a_size;
  184.             size += taxp->a_size;
  185.             taxp = taxp->a_axp;
  186.         }
  187.     }
  188.     tap->a_size = size;
  189.     if ((tap->a_flag&A_PAG) && (size > 256))
  190.         fprintf(stderr,
  191.             "\n?ASlink-W-Paged Area %.8s Length Error\n", tap->a_id);
  192. }
  193.